home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / yerk / mps231ss.hqx / Mops source / Module source / windowmod.txt < prev    next >
Text File  |  1993-02-03  |  10KB  |  394 lines

  1. \ Window class.
  2.  
  3. \  May 91 mrh    Added NonScrollWind.
  4. \    Default grow and drag limits set at grow and drag time.
  5. \    Also fixed a number of long-standing bugs in draw:, enable:, disable:
  6. \    etc.  New: deactivates current window.  Added PenIntoWind:.
  7.  
  8.  
  9. \        ===================================
  10.  
  11. \ WINDOW is the basic window class, with no controls.
  12. \  For windows with controls, use Window+.
  13.  
  14. \        ===================================
  15.  
  16. :class    WINDOW  super{ grafPort }
  17.  
  18.   $ 20    bytes    wind1            \ unmapped
  19.         handle    CTLLIST            \ 1st ctl
  20.   $ 0C    bytes    wind2            \ unmapped
  21.  
  22.         rect    CONTRECT        \ true content
  23.         rect    GROWRECT        \ grow size rectangle
  24.         rect    DRAGRECT        \ drag limits rect
  25.  
  26.         bool    GROWFLG            \ true if growable
  27.         bool    DRAGFLG            \ true if draggable
  28.         bool    ALIVE            \ true if space exists
  29.         bool    SCROLLFLG        \ true if scrollable
  30.  
  31.         x-addr    IDLE            \ idle handler
  32.         x-addr    DEACT            \ deactivate event handler
  33.  
  34.         x-addr    CONTENT            \ content handler
  35.         x-addr    DRAW            \ draw handler
  36.         x-addr    ENACT            \ activate event handler
  37.         x-addr    CLOSE            \ close handler
  38.  
  39.         int        RESID            \ resource id
  40.  
  41. private
  42.  
  43. :m SETLIMITS:    \ Sets GrowRect and DragRect to reasonable default values
  44.                 \ according to the current screen size at the time the grow
  45.                 \ or drag is done.  Programs such as SteppingOut can change
  46.                 \ the screen size while a window is open!
  47.  
  48.     screenbits  put: dragRect
  49.     40 40 getBot: dragRect  put: growRect
  50.     4 4 inset: dragRect  ;m
  51.  
  52. :m ?SETFPRECT:    \ Sets fPrect if scrollFlg is true.  fPrect is needed by
  53.                 \ the nucleus for scrolling fWind, before proper window
  54.                 \ handling is loaded.  But it can be used for scrolling
  55.                 \ text in any other window as well, if scrolling is enabled
  56.                 \ for that window.
  57.  
  58.     get: scrollFlg IF  get: contRect  put: fPrect  THEN  ;m
  59.  
  60. :m ?DISABLE_ACTW:    \ Deactivates the currently active window before a New:
  61.                     \ or GetNew: call, if there is a currently active Mops 
  62.                     \ window.
  63.     actW  0EXIT
  64.     disable: actW  0 -> actW  ;m
  65.  
  66. :m InitNewWindow:
  67.     setContRect: [self]
  68.     set: self  initfont  true  put: alive
  69.     cls  ;m
  70.  
  71. :m PenIntoWind:    \ Moves the GrafPort pen back into the window area if
  72.                 \ necessary, after the window has been resized.
  73.                 \ Actually at the moment we only worry about the vertical
  74.                 \ direction.
  75.     @xy bottom min  gotoxy  ;m
  76.  
  77. public
  78.  
  79. :m SETCONTRECT:    \ Sets ContRect to the viewing area.  Must be public since 
  80.                 \ we late-bind to it, and it gets called from ObjInit anyway.
  81.  
  82.     get: portRect  get: growFlg
  83.     IF  swap 15 -  swap  15 -  THEN   put: contRect
  84.     ?setfPrect: self  ;m
  85.  
  86. :m CLOSE:
  87.     get: alive  0exit
  88.     ^base  call CloseWindow
  89.     clear: alive   exec: close  ;m
  90.  
  91. :m RELEASE:    close: [self]  ;m    \ Standard destructor - same as close.
  92.  
  93. :m SET:        \ Makes this wind the current GrafPort.  It used
  94.             \ to call setContRect: but there's really no need.
  95.     set: super
  96.     ?setfPrect: self  ;m
  97.  
  98. :m UPDATE:    \ Generates an update event for the window with its
  99.             \  entire port rectangle as the update region.
  100.     pushPort  set: self
  101.     getRect: self  put: tempRect  update: tempRect
  102.     popPort  ;m
  103.  
  104.  
  105. :m NEW: { bndsRect tAddr tLen procID vis goAway \ s255 -- }
  106.  
  107.   \ Defines a new window on the heap with the specified features.
  108.   \ Not resource based.
  109.  
  110.     get: alive  ?EXIT                    \ Out if already alive
  111.     ?disable_actW: self
  112.     tAddr tLen  str255  -> s255
  113.     0  ^base  bndsrect  s255  vis Tbool
  114.     procID makeint
  115.     inFront  goAway Tbool  0
  116.     call NewWindow  drop
  117.     initNewWindow: self  ;m
  118.  
  119.  
  120. :m GETNEW:        \ ( resid -- )   Resource based new window.
  121.  
  122.     get: alive  IF  drop  EXIT  THEN    \ Out if already alive
  123.     ?disable_actW: self
  124.     dup  put: resid  0 swap makeint ^base  0
  125.     call GetNewWindow  drop
  126.     initNewWindow: self  ;m
  127.  
  128.  
  129. :m GETRECT:        \ ( -- l t r b )  Returns the port rect
  130.     get: portRect  ;m
  131.  
  132. :m GETVSRECT:    \ ( l t r b -- l' t' r' b' )
  133.                 \ Returns the default vert. scroll bar rect.
  134.     get: portRect  >vrect  ;m
  135.  
  136. :m GETHSRECT:    \ ( l t r b -- l' t' r' b' )
  137.                 \ Returns the default horiz. scroll bar rect.
  138.     get: portRect  >hrect  ;m
  139.  
  140.  
  141. \ The DRAW: method is called, late-bound, whenever a window is updated.
  142. \ The implementation must begin with a BeginUpdate call and end with an
  143. \ EndUpdate call.  We use the CallFirst/CallLast mechanism to ensure this,
  144. \ and also to draw the grow icon if this is a growable window.  This means
  145. \ that any redefinition of DRAW: in a subclass should not call DRAW: super,
  146. \ since this would lead to BeginUpdate and EndUpdate being called more than
  147. \ once.  So we define another method (DRAW): to do the actual work for DRAW:,
  148. \ and subclasses which need their own versions of DRAW: may call (DRAW):
  149. \ freely.
  150.  
  151. private
  152.  
  153. :m (DRAW):        \ Does the main work for DRAW:.
  154.     savePort  @xy  set: self        \ Save port and pen posn, reset to this 
  155.                                     \  window
  156.     exec: draw                        \ Call user draw routine
  157.     restport gotoxy  ;m                \ Restore pen posn, restore original port
  158.  
  159.  
  160. :m SETUP_DRAW:
  161.     get: fPrect                        \ Save fPrect as it might get changed
  162.     ^base  call BeginUpdate  ;m
  163.  
  164. :m WINDUP_DRAW:
  165.     get: growFlg
  166.     IF    @xy
  167.         ^base  call DrawGrowIcon
  168.         gotoxy
  169.     THEN
  170.     ^base  call EndUpdate
  171.     put: fPrect  ;m                    \ Restore fPrect
  172.  
  173.  
  174. callFirst    setup_draw:
  175. callLast    windup_draw:
  176.  
  177. public
  178.  
  179. :m DRAW:    (draw): self  ;m
  180.  
  181.  
  182. :m SELECT:        \ Makes this the front window.
  183.     ^base  call SelectWindow
  184.     ?setfPrect: self  ;m
  185.  
  186.  
  187. \ The idle: method is called for the frontmost window, whenever a null
  188. \ event occurs.  NULL-EVT is the normal word which sends idle:.  In
  189. \ subclasses we redefine this method to do things like calling TEidle,
  190. \ which have to be done periodically.  The Idle handler is also called,
  191. \ which allows a window-specific action to be taken.  In the class Window
  192. \ itself, this is all we do.
  193.  
  194. :m IDLE:        exec: idle  ;m
  195.  
  196. :m SETIDLE:        put: idle  ;m
  197.  
  198.  
  199. :m ENABLE:        \ Handles an activate event.
  200.     set: self
  201.     get: growFlg  IF  @xy  ^base  call DrawGrowIcon  gotoxy  THEN
  202.     exec: enact  ;m
  203.  
  204. :m DISABLE:        \ Handles a deactivate event.
  205.     get: growFlg
  206.     IF                                    \ We need to erase the grow icon
  207.         @xy  get: tempRect                \ Save things
  208.         getRect: self  put: tempRect
  209.         getBotX: tempRect  14 -  putTopX: tempRect
  210.         getBotY: tempRect  14 -  putTopY: tempRect
  211.         clear: tempRect
  212.         put: tempRect  gotoxy            \ Restore
  213.     THEN
  214.     exec: deact  ;m
  215.  
  216.  
  217. :m ACTIONS:        \ ( close enact draw cont 4 -- )
  218.                 \ Sets up window event handler words.  We require
  219.                 \ an xt count as this is normal for actions: methods.
  220.     4 ?#xts
  221.     put: content  put: draw  put: enact  put: close  ;m
  222.  
  223.  
  224. :m SETACT:    \ ( enact deact -- )  Sets just the activate/deactivate
  225.             \ event handlers
  226.     put: deact  put: enact  ;m
  227.  
  228.  
  229. :m SETDRAW:        \ ( xt -- )  Sets the draw handler
  230.     put: draw  ;m
  231.  
  232.  
  233. :m ACTIVE:    \ ( -- b )  Is this window active ?
  234.     0  call FrontWindow  ^base  =  ;m
  235.  
  236.  
  237. :m ALIVE:    \ ( -- b )  Is this window alive?
  238.     get: alive  ;m
  239.  
  240.  
  241. :m DRAG:    \ Handles a drag region click
  242.     setLimits: self                    \ Omit in subclasses which need
  243.                                     \  custom drag limits
  244.     get: dragFlg  0exit
  245.     ^base  whrFEv  addr: dragRect
  246.     call DragWindow  ;m
  247.  
  248. private
  249.  
  250. \ Some housekeeping routines for Size: and Zoom:
  251.  
  252. :m ClrOldBars:
  253.     getVSrect: self 16 +  put: tempRect
  254.     clear: tempRect  update: tempRect    \ Including the grow box
  255.     getHSrect: self  put: tempRect
  256.     clear: tempRect  update: temprect  ;m
  257.  
  258. :m FixNewBars:
  259.     ClrOldBars: self                    \ Yes, the code's the same so far!!
  260.     addr: portRect  call ClipRect
  261.     setContRect: [self]
  262.     penIntoWind: self  ;m
  263.  
  264. public
  265.  
  266. :m SIZE:    \ ( w h -- )  Resizes window and accumulates update regions.
  267.     pack  ^base  swap  true makeint
  268.     ClrOldBars: self
  269.     call SizeWindow
  270.     FixNewBars: self  ;m
  271.  
  272. :m SETSIZE:    size: self  ;m    \ For naming consistency with Rects and 
  273.                             \  Views.
  274.  
  275.  
  276. :m MOVE:    \ ( x y -- )  Moves the window.
  277.     pack  ^base  swap  w 0
  278.     call MoveWindow  ;m
  279.  
  280.  
  281. :m CENTER:  { \ sw sh pw ph -- }
  282.         \ Centers the window on the screen.
  283.         \ Yeah, I know, here in Oz we spell this "centre", but we Ozzies
  284.         \ are more flexible than the Yanks, so we'll magnanimously do it
  285.         \ their way, not ours.
  286.         
  287.     screenbits  -> sh  -> sw  2drop
  288.     size: portRect  -> ph  -> pw
  289.     sw pw - 2/  sh ph - 2/  move: self  ;m
  290.  
  291.  
  292. :m ZOOM:  { part -- }
  293.     word0  ^base  whrFEv
  294.     part makeint  call TrackBox  i->l
  295.     IF    getRect: self  put: tempRect  tempRect  call EraseRect
  296.         ^base  part makeint  word0  call ZoomWindow
  297.         FixNewBars: self
  298.     THEN  ;m
  299.  
  300.  
  301. :m GROW:        \ Handles a mouse-down in the grow box.
  302.     get: growFlg
  303.     IF    setLimits: self                    \ Omit in subclasses which need
  304.                                         \  custom grow limits
  305.         0 ^base  whrFEv  addr: growrect
  306.         call GrowWindow  ?dup
  307.         IF    unpack  size: self  draw: self
  308.             penIntoWind: self
  309.         THEN
  310.     THEN
  311.     ^base  call SelectWindow
  312.     update: self  ;m
  313.  
  314.  
  315. :m CONTENT:        \ Handles a content click.
  316.     active: self
  317.     IF        exec: content
  318.     ELSE    select: self
  319.     THEN  ;m
  320.  
  321.  
  322. :m TITLE:    \ ( addr len -- )  Sets the title of the window.
  323.     str255  ^base  swap  call SetWTitle  ;m
  324.  
  325. :m NAME:  ( addr len -- )    title: self  ;m        \ An alias for TITLE:.
  326.  
  327.  
  328. :m GETNAME:    \ ( -- addr len )  Returns name of window.
  329.     ^base  buf255  call GetWTitle
  330.     buf255 count  ;m
  331.  
  332.  
  333. :m MAXX:    \ ( -- x )  Returns the x coordinate value corresponding to
  334.             \  the window being moved to the right of the screen.
  335.     screenbits drop nip nip
  336.     size: portRect  drop  -  ;m
  337.  
  338.  
  339. :m MAXY:    \ ( -- y )
  340.     screenbits nip nip nip
  341.     size: portRect  nip  -  ;m
  342.  
  343. \            =================
  344.  
  345. :m KEY:        \ ( c -- )  May be used in subclasses to do something with
  346.             \  typed keys.  Here, we just drop it.
  347.     drop  ;m
  348.  
  349.  
  350. :m SHOW:    ^base  call ShowWindow  ;m
  351.  
  352. :m HIDE:    ^base  call HideWindow  ;m
  353.  
  354.  
  355. :m SETGROW:    \ ( l t r b  T  |  F -- )  Sets grow limits, if boolean is true.
  356.  
  357.     \ Note: in class Window itself, we IGNORE these grow limits and
  358.     \  use a default value based on the size of the screen at the time
  359.     \  the grow is actually done.
  360.  
  361.     dup  put: growFlg
  362.     if  put: growrect  then  ;m
  363.  
  364. :m SETDRAG:    \ ( l t r b  T  |  F -- )  Sets drag limits.
  365.  
  366.     \ Note: in class Window itself, we IGNORE these drag limits and
  367.     \  use a default value based on the size of the screen at the time
  368.     \  the drag is actually done.
  369.  
  370.     dup  put: dragFlg
  371.     if  put: dragRect  then  ;m
  372.  
  373. :m SETSCROLL:    \ ( b -- )
  374.     put: scrollFlg  ;m
  375.  
  376.  
  377. :m CLASSINIT:
  378.     xts{ null null null null }  actions: self
  379.     ['] null  dup  put: idle  put: deact
  380.     true  put: scrollFlg  true  put: dragFlg  ;m
  381.  
  382.  
  383. :m MARKALIVE:    \ A special method really intended just to allow us to
  384.                 \ mark fWind alive on startup.
  385.     true  put: alive   ;m
  386.  
  387.  
  388. :m TEST:        \ Fires up a test window.
  389.     100 100 300 200 put: tempRect
  390.     screenbits true setGrow: self
  391.     tempRect  " Test"  docWind  true true  new: self  ;m
  392.  
  393. ;class
  394.